package com.dd.cloud.user.service.chknowl.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.dd.cloud.common.constants.ChKnowlConstants;
import com.dd.cloud.common.constants.SearchConstants;
import com.dd.cloud.user.entity.chknowl.ChknowlFoodModel;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.user.mapper.chknowl.ChknowlFoodModelMapper;
import com.dd.cloud.user.req.chknowl.FoodModelCreateReq;
import com.dd.cloud.user.req.chknowl.FoodModelQueryReq;
import com.dd.cloud.user.req.chknowl.FoodModelUpdateReq;
import com.dd.cloud.user.res.chknowl.ChUserSearchRes;
import com.dd.cloud.user.res.chknowl.ChknowlFoodModelPageRes;
import com.dd.cloud.user.service.chknowl.IChknowlFoodModelService;
import com.dd.cloud.user.service.search.ISearchHotService;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.common.enums.ZkExceptionEnum;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.utils.*;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 药食同源基础表 服务实现类
 * </p>
 *
 * @author czg
 * @since 2022-07-04
 */
@Service
public class ChknowlFoodModelServiceImpl extends ServiceImpl<ChknowlFoodModelMapper, ChknowlFoodModel> implements IChknowlFoodModelService {

    @Autowired
    public FastFileStorageClient storageClient;
    @Autowired
    private ISearchHotService searchHotService;

    /**
     * 分页查询食疗方
     *
     * @param req 多条件
     * @return
     */
    @Override
    public IPage<ChknowlFoodModelPageRes> queryFoodModelTerms(FoodModelQueryReq req) {
        req.setStatus(StringUtils.isBlank(req.getStatus()) ? "1,2" : req.getStatus());
        if (!StringUtils.isBlank(req.getStatus())){
            req.setStatusStr(req.getStatus().split(","));
        }
        IPage<ChknowlFoodModelPageRes> iPage = req.pagePojo();
        iPage = getBaseMapper().getDrugsFoodModelTerms(iPage, req);
        if (!StringUtils.isBlank(req.getKeyword())) {
            searchHotService.saveSearchHot(SearchConstants.Modular.CHSCIENCE, SearchConstants.ChscienceSubmodule.FOOD, req.getKeyword());
        }
        return iPage;
    }


    /**
     * 通过id查询药食同源详细信息
     *
     * @param id 编号
     * @return
     */
    @Override
    public ChknowlFoodModelPageRes queryFoodModel(Integer id) {
        ChknowlFoodModelPageRes dfm = getBaseMapper().getChknowlFoodModelById(id);
        return dfm;
    }

    /**
     * 添加药食同源数据
     * @param req 药食同源药材信息
     */
    @Override
    public void addFoodModel(FoodModelCreateReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.ADMIN).get();
        QueryWrapper<ChknowlFoodModel> qq = new QueryWrapper<>();
        qq.lambda().select(ChknowlFoodModel::getId)
                .eq(ChknowlFoodModel::getName, req.getName())
                .ne(ChknowlFoodModel::getStatus, ChKnowlConstants.ContentStatus.DELETE);
        ChknowlFoodModel dfm = getOne(qq);
        if (dfm != null){
            throw new ZekeException(400, "药食同源名字已存在");
        }
        if (!ObjectUtils.refrect(ChKnowlConstants.ContentStatus.class, req.getStatus())){
            throw new ZekeException(ZkExceptionEnum.STATUS_DATA_ERROR);
        }
        dfm = new ChknowlFoodModel();
        BeanUtils.copyProperties(req, dfm);
        if (StringUtils.isBlank(dfm.getNamePinyin())) {
            //拼音
            dfm.setNamePinyin(PinYinUtils.chineseToPinyin(dfm.getName()));
        }
        if (req.getSort() == null || req.getSort() < 1) {
            QueryWrapper<ChknowlFoodModel> qw = new QueryWrapper<>();
            qw.lambda().orderByDesc(ChknowlFoodModel::getSort);
            qw.last("limit 1");
            ChknowlFoodModel temp = getOne(qw);
            if (temp == null || temp.getSort() == null) {
                dfm.setSort(1);
            } else {
                dfm.setSort(temp.getSort() + 1);
            }
        } else {
            UpdateWrapper<ChknowlFoodModel> uw = new UpdateWrapper<>();
            uw.lambda().ge(ChknowlFoodModel::getSort, req.getSort());
            uw.setSql("sort = sort + 1");
            update(uw);
        }
        dfm.setStatus(dfm.getStatus() == null ? 1 : dfm.getStatus());
        dfm.setCreateDate(LocalDateTime.now());
        dfm.setOperId(loginInfo.getId());
        dfm.setOperDate(LocalDateTime.now());
        boolean flag = save(dfm);
        if (!flag) {
            throw new ZekeException(ZkExceptionEnum.ADD_ERROR);
        }
    }

    /**
     * 修改药食同源
     * @param req 药食同源药材信息
     */
    @Override
    public void updateFoodModel(FoodModelUpdateReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.ADMIN).get();
        ChknowlFoodModel model = getById(req.getId());
        if (model == null || model.getStatus() == ChKnowlConstants.ContentStatus.DELETE){
            throw new ZekeException(400, "中成药信息不存在");
        }
        if (!model.getName().equals(req.getName())){
            //修改了药品名, 判断药品名是否存在
            QueryWrapper<ChknowlFoodModel> qw = new QueryWrapper<>();
            qw.lambda().eq(ChknowlFoodModel::getName, req.getName())
                    .select(ChknowlFoodModel::getId)
                    .ne(ChknowlFoodModel::getStatus, ChKnowlConstants.ContentStatus.DELETE);
            ChknowlFoodModel patent = getOne(qw);
            if (patent != null){
                throw new ZekeException(400, "药品名已存在");
            }
        }
        if (!ObjectUtils.refrect(ChKnowlConstants.ContentStatus.class, req.getStatus())){
            throw new ZekeException(ZkExceptionEnum.STATUS_DATA_ERROR);
        }
        BeanUtils.copyProperties(req, model);
        model.setOperId(loginInfo.getId());
        model.setOperDate(LocalDateTime.now());
        if (model.getNamePinyin() == null || model.getNamePinyin().equals("")) {
            //拼音
            model.setNamePinyin(PinYinUtils.chineseToPinyin(model.getName()));
        }
        if (req.getSort() == null || req.getSort() < 1) {
            QueryWrapper<ChknowlFoodModel> qw = new QueryWrapper<>();
            qw.lambda().orderByDesc(ChknowlFoodModel::getSort);
            qw.last("limit 1");
            ChknowlFoodModel temp = getOne(qw);
            if (temp == null || temp.getSort() == null) {
                model.setSort(1);
            } else {
                model.setSort(temp.getSort() + 1);
            }
        } else {
            QueryWrapper<ChknowlFoodModel> qw = new QueryWrapper<>();
            qw.lambda().eq(ChknowlFoodModel::getId, req.getId());
            qw.lambda().select(ChknowlFoodModel::getSort);
            ChknowlFoodModel temp = getOne(qw);
            if (!temp.getSort().equals(req.getSort())) {
                UpdateWrapper<ChknowlFoodModel> uw = new UpdateWrapper<>();
                uw.lambda().ge(ChknowlFoodModel::getSort, req.getSort());
                uw.setSql("sort = sort + 1");
                update(uw);
            }
        }
        boolean flag = updateById(model);
        if (!flag) {
            throw new ZekeException(ZkExceptionEnum.ADD_ERROR);
        }
    }

    /**
     * 修改药食同源状态
     * @param id     信息id
     * @param status 状态
     */
    @Override
    public void updateFoodModelStatus(Integer id, Integer status) {
        ChknowlFoodModel md = getById(id);
        if (md == null){
            throw new ZekeException(400, "药品id不存在");
        }
        if (!ObjectUtils.refrect(ChKnowlConstants.ContentStatus.class, status)){
            throw new ZekeException(ZkExceptionEnum.STATUS_DATA_ERROR);
        }
        md.setStatus(status);
        boolean flag = updateById(md);
        if (!flag) {
            throw new ZekeException(ZkExceptionEnum.UPDATE_ERROR);
        }
    }

    /**
     * excel批量导入药食同源
     * @param file excel文件
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void addBatchFoodModel(MultipartFile file) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.ADMIN).get();
        if (file == null) {
            throw new ZekeException(400, "请上传文件");
        }
        if (!file.getOriginalFilename().contains(".xlsx") && !file.getOriginalFilename().contains(".xls")) {
            throw new ZekeException(400, "只支持xlsx和xls文件格式");
        }
        List<ChknowlFoodModel> list = new ArrayList<>();
        try {
            list = ExtUtils.importExcel(file, 0, 1, ChknowlFoodModel.class);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ZekeException(400, "解析Excel失败");
        }
        if (list == null || list.isEmpty()){
            throw new ZekeException(400, "文档数据为空");
        }

        List<String> exists = getBaseMapper().getChknowlFoodModelNameIsExists(list.stream().map(ChknowlFoodModel::getName).collect(Collectors.toList()));
        if (exists != null && !exists.isEmpty()){
            throw new ZekeException(400, "以下药品名已存在:"+ StringUtils.join(exists, ","));
        }

        list.stream().forEach(foodModel -> {
            ValidatorUtils.verify(foodModel, ChknowlFoodModel.class);
            foodModel.setCreateDate(LocalDateTime.now());
            foodModel.setNamePinyin(PinYinUtils.chineseToPinyin(foodModel.getName()));
            foodModel.setStatus(ChKnowlConstants.ContentStatus.NORMAL);
            foodModel.setOperId(loginInfo.getId());
            foodModel.setOperDate(LocalDateTime.now());
            if (!StringUtils.isBlank(foodModel.getImgUrl())) {
                try {
                    File f = new File(foodModel.getImgUrl());
                    InputStream fis = new FileInputStream(f);
                    MultipartFile multipartFile = new MockMultipartFile("file", f.getName(), "image/jpg", IOUtils.toByteArray(fis));
                    String imgUrl = UploadUtil.uploadImage(multipartFile,storageClient);
                    foodModel.setImgUrl(imgUrl);
                } catch (Exception ex) {
                    ex.printStackTrace();
                    throw new ZekeException(400, "文档图片下载失败");
                }
            }
        });
        Integer flag = getBaseMapper().insertBatchSomeColumn(list);
        if (flag <= 0) {
            throw new ZekeException(400, "批量导入数据失败");
        }
//        try {
//
//            Workbook workbook = WorkbookFactory.create(file.getInputStream());
//            Sheet sheet = workbook.getSheetAt(0);
//            List<ChknowlFoodModel> list = new ArrayList<>(100);
//            ChknowlFoodModel dfm;
//            QueryWrapper<ChknowlFoodModel> qw = new QueryWrapper<>();
//            qw.lambda().select(ChknowlFoodModel::getSort);
//            qw.lambda().orderByDesc(ChknowlFoodModel::getSort);
//            qw.last("limit 1");
//            Integer sort = getOne(qw).getSort();
//            //行数 跳过标题
//            int i = 1;
//            while (i <= sheet.getLastRowNum()) {
//                Row row = sheet.getRow(i);
//                if (row == null) {
//                    i++;
//                    continue;
//                }
//                int k = 0;
//                dfm = new ChknowlFoodModel();
//                while (k <= row.getLastCellNum()) {
//                    Cell cell = row.getCell(k);
//                    if (cell == null) {
//                        if (k == 0) {
////                            dfm.setSerialNumber(++serialNumber);
//                        } else if (k == 1 || k == 2 || k == 5) {
//                            throw new ZekeException(400, "有必填项,未填,位置:" + (i + 1) + "行," + (k + 1) + "列");
//                        }
//                        k++;
//                        continue;
//                    }
//                    cell.setCellType(CellType.STRING);
//                    String val = cell.getStringCellValue();
//                    switch (k) {
//                        case 0:
//                            break;
//                        case 1:
//                            dfm.setName(val);
//                            break;
//                        case 2:
//                            dfm.setNamePinyin(val);
//                            break;
//                        case 3:
//                            dfm.setBotanyName(val);
//                            break;
//                        case 4:
//                            dfm.setPosition(val);
//                            break;
//                        case 5:
//                            dfm.setEffect(val);
//                            break;
//                        case 6:
//                            dfm.setPrecautions(val);
//                            break;
//                        default:
//                    }
//                    k++;
//                }
//                dfm.setSort(++sort);
//                dfm.setStatus(1);
//                dfm.setCreateDate(LocalDateTime.now());
//                list.add(dfm);
//                if (list.size() == 100) {
//                    boolean flag = saveBatch(list);
//                    if (!flag) {
//                        throw new ZekeException(400, "批量导入数据失败");
//                    }
//                    list = new ArrayList<>(100);
//                }
//                i++;
//            }
//            if (list.size() > 0) {
//                boolean flag = saveBatch(list);
//                if (!flag) {
//                    throw new ZekeException(400, "批量导入数据失败");
//                }
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
    }

    /**
     * 关键字搜索食疗方
     *
     * @param keyword
     * @return
     */
    @Override
    public ChUserSearchRes getUserSearchRes(String keyword) {
        if (StringUtils.isBlank(keyword)) {
            throw new ZekeException("搜索关键字不能为空");
        }
        ChUserSearchRes res = new ChUserSearchRes();
//        List<DrugsUserSearchListRes> list1 = getBaseMapper().getDrugsFoodModelListByKeyword(keyword);
//        List<DrugsUserSearchListRes> list2 = drugsChineseExplainService.getMiddleDrugsListByKeyword(keyword);
//        List<DrugsUserSearchListRes> list3 = drugsPatentExplainService.getMiddlePatentDrugsListByKeyword(keyword);
//        res.setList1(list1);
//        res.setList2(list2);
//        res.setList3(list3);
        return res;
    }
}
